package com.aitangbao.web.controller;

import java.io.*;
import java.sql.SQLException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.hutool.core.io.FileUtil;
import com.aitangbao.core.model.KJobTrans;
import com.aitangbao.web.utils.ZipUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.aitangbao.common.toolkit.Constant;
import com.aitangbao.core.dto.BootTablePage;
import com.aitangbao.core.dto.ResultDto;
import com.aitangbao.core.model.KJob;
import com.aitangbao.core.model.KUser;
import com.aitangbao.web.service.JobService;
import com.aitangbao.web.utils.JsonUtils;


@RestController
@RequestMapping("/job/")
@Slf4j
public class JobController {

    @Autowired
    private JobService jobService;


    @RequestMapping("getSimpleList.shtml")
    public String getSimpleList(HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        return JsonUtils.objectToJson(jobService.getList(kUser.getUId()));
    }


    @RequestMapping("getList.shtml")
    public String getList(Integer offset, Integer limit, Integer categoryId, String jobName, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        BootTablePage list = jobService.getList(offset, limit, categoryId, jobName, kUser.getUId());
        return JsonUtils.objectToJson(list);
    }

    @RequestMapping("delete.shtml")
    public String delete(Integer jobId) {
        jobService.delete(jobId);
        return ResultDto.success();
    }

    @RequestMapping("uploadJob.shtml")
    public String uploadJob(MultipartFile jobFile, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        try {
            String saveFilePath = jobService.saveFile(kUser.getUId(), jobFile);
            return ResultDto.success(saveFilePath);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }


    @RequestMapping("insert.shtml")
    public String insert(KJob kJob, String customerQuarz, HttpServletRequest request, @RequestParam(value = "jobFile", required = false) MultipartFile jobFile,
                         @RequestParam(value = "transFiles", required = false) MultipartFile[] transFiles) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        Integer uId = kUser.getUId();

        //类型文件的时候， 才可以保存
        if (kJob.getJobType() == 2) {
            //校验作业跟转换
            if (!this.validKjbFile(jobFile, false) || !this.validKtrFiles(transFiles, false)) {
                return ResultDto.fail("上传作业或者转换文件有误");
            }
            //保存文件, 校验
            try {
                KJobTrans kJobTrans = jobService.saveJobFileAndTransFile(uId, jobFile, transFiles);
                kJob.setJobPath(kJobTrans.getJobPath());
                kJob.setJobTransPath(kJobTrans.getJobTransPath());
            } catch (IOException e) {
                log.error("保存作业以及转换异常", e);
                return ResultDto.fail("保存作业以及转换异常");
            } catch (Exception e) {
                log.error("更新作业以及转换异常", e);
                return ResultDto.fail("保存作业以及转换异常");
            }
        }

        if (jobService.check(kJob.getJobRepositoryId(), kJob.getJobPath(), uId)) {
            try {
                jobService.insert(kJob, uId, customerQuarz);
                return ResultDto.success();
            } catch (SQLException e) {
                e.printStackTrace();
                return ResultDto.fail("添加作业失败");
            }
        } else {
            return ResultDto.fail("该作业已经添加过了");
        }
    }


    @RequestMapping("getJob.shtml")
    public String getJob(Integer jobId) {
        return ResultDto.success(jobService.getJob(jobId));
    }

    @RequestMapping("update.shtml")
    public String update(KJob kJob, String customerQuarz, HttpServletRequest request, @RequestParam(value = "jobFile", required = false) MultipartFile jobFile,
                         @RequestParam(value = "transFiles", required = false) MultipartFile[] transFiles) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        Integer uId = kUser.getUId();

        //类型文件的时候， 才可以修改
        if (kJob.getJobType() == 2) {
            //前端禁止修改job跟trans地址，只能上传文件修改路径
            kJob.setJobPath(null);
            kJob.setJobTransPath(null);
            //校验作业跟转换
            if (!this.validKjbFile(jobFile, true) || !this.validKtrFiles(transFiles, true)) {
                return ResultDto.fail("上传作业或者转换文件有误");
            }
            //保存文件
            if ((jobFile != null && !jobFile.isEmpty()) || (transFiles != null && transFiles.length > 0 && StringUtils.isNotEmpty(transFiles[0].getOriginalFilename()))) {
                try {
                    KJobTrans kJobTrans = jobService.updateJobFileAndTransFile(kJob.getJobId(), uId, jobFile, transFiles);
                    kJob.setJobPath(kJobTrans.getJobPath());
                    kJob.setJobTransPath(kJobTrans.getJobTransPath());
                    kJob.setJobPath(kJobTrans.getJobPath());
                    kJob.setJobTransPath(kJobTrans.getJobTransPath());
                } catch (IOException e) {
                    log.error("更新作业以及转换异常", e);
                    return ResultDto.fail("保存作业以及转换异常");
                } catch (Exception e) {
                    log.error("更新作业以及转换异常", e);
                    return ResultDto.fail("保存作业以及转换异常");
                }
            }
        }
        try {
            jobService.update(kJob, customerQuarz, uId);
            return ResultDto.success();
        } catch (Exception e) {
            return ResultDto.success(e.toString());
        }
    }

    @RequestMapping("start.shtml")
    public String start(Integer jobId) {
        jobService.start(jobId);
        return ResultDto.success();
    }

    @RequestMapping("stop.shtml")
    public String stop(Integer jobId) {
        jobService.stop(jobId);
        return ResultDto.success();
    }

    @RequestMapping("startAll.shtml")
    public String startAll(Integer categoryId, String jobName, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        jobService.startAll(categoryId, jobName, kUser.getUId());
        return ResultDto.success();
    }

    @RequestMapping("stopAll.shtml")
    public String stopAll(Integer categoryId, String jobName, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        jobService.stopAll(categoryId, jobName, kUser.getUId());
        return ResultDto.success();
    }

    @RequestMapping("getStartTaskCount.shtml")
    public String getStartTaskCount(Integer categoryId, String jobName, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        return JsonUtils.objectToJson(jobService.getStartTaskCount(categoryId, jobName, kUser.getUId()));
    }

    @RequestMapping("getStopTaskCount.shtml")
    public String getStopTaskCount(Integer categoryId, String jobName, HttpServletRequest request) {
        KUser kUser = (KUser) request.getSession().getAttribute(Constant.SESSION_ID);
        return JsonUtils.objectToJson(jobService.getStopTaskCount(categoryId, jobName, kUser.getUId()));
    }

    @RequestMapping({"getJobRunState.shtml"})
    public String getJobRunState(Integer jobId) {
        return JsonUtils.objectToJson(this.jobService.getJobRunState(jobId));
    }

    /**
     * 判断作业是否存在根据jobid
     *
     * @param jobId
     * @return
     */
    @RequestMapping({"judgeHaveJobFile.shtml"})
    @ResponseBody
    public String judgeHaveJobFile(Integer jobId) {
        try {
            KJob kJob = jobService.getJob(jobId);
            String jobPath = kJob.getJobPath();
            File file = new File(jobPath);
            if (!FileUtil.exist(file)) {
                return ResultDto.fail("作业文件丢失！");
            }
        } catch (Exception e) {
            log.error("下载作业异常", e);
            return ResultDto.fail("下载作业异常");
        }
        return ResultDto.success();
    }

    /**
     * 下载文件根据jobid， 调用接口之前，理应调用上个接口：判断文件是否存在
     *
     * @param jobId
     * @param response
     */
    @RequestMapping({"downloadByJobId.shtml"})
    public void downloadByJobId(Integer jobId, HttpServletResponse response) {
        // 定义压缩包名称
        try {
            KJob kJob = jobService.getJob(jobId);
            String jobPath = kJob.getJobPath();

            File file = new File(jobPath);
            if (!FileUtil.exist(file)) {
                log.error("文件丢失！");
                throw new RuntimeException("下载作业：文件丢失");
            }
            //压缩并下载文件
            this.zipAndDown(kJob, response);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

    }

    /**
     * 压缩到临时目录, 下载文件， 删除临时目录
     *
     * @param kJob
     * @return
     */
    private void zipAndDown(KJob kJob, HttpServletResponse response) {
        //查询当前要下载的目录
        String jobPath = kJob.getJobPath();
        int lastPathFlag = jobPath.lastIndexOf("/");
        String jobParentPath = jobPath.substring(0, lastPathFlag + 1);
        //下载的zip名称
        String zipName = kJob.getJobName() + ".zip";
        //临时目录
        String tempPath = Thread.currentThread().getContextClassLoader().getResource("").getPath() + "temp" + File.separator;
        File tempFile = new File(tempPath);
        if (!tempFile.exists()) {
            tempFile.mkdirs();
        }
        String zipPath = tempPath + zipName;
        //压缩文件到临时目录
        ZipUtils.compressToZip(jobParentPath, tempPath, zipName);
        //文件下载
        ZipUtils.download(zipPath, response);
        //删除临时文件
        FileUtil.del(zipPath);
    }


    /**
     * 校验作业文件
     *
     * @param file
     * @param allowEmpty 是否允许空
     * @return
     */
    private Boolean validKjbFile(MultipartFile file, Boolean allowEmpty) {
        //如果是空，并且允许空值，返回true， 是空不允许空值， 返回false
        if (file == null || file.isEmpty()) {
            return allowEmpty;
        }
        //判断后缀如果不是kjb，返回false， 否则返回true
        String fileName = file.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
        if ("kjb".equals(suffix)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 校验转换文件
     *
     * @param files
     * @param allowEmpty 是否允许空
     * @return
     */
    private Boolean validKtrFiles(MultipartFile[] files, Boolean allowEmpty) {
        //如果是空，并且允许空值，返回true， 是空不允许空值， 返回false
        if (files == null || files.length == 0 || (files.length == 1 && StringUtils.isEmpty(files[0].getOriginalFilename()))) {
            return allowEmpty;
        }
        //遍历加标志， 如果都是ktr， 返回true， 否则返回false
        int flag = 0;
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            String suffix = fileName.substring(fileName.lastIndexOf(".") + 1);
            if (!"ktr".equals(suffix)) {
                flag++;
            }
        }
        if (flag == 0) {
            return true;
        } else {
            return false;
        }
    }


}
